﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using BizElements.BusinessLayer;

namespace BizElements.Web
{
    /// <summary>
    /// Creates grid footers which compute and display the average of all values in a numeric column.
    /// </summary>
    [Serializable]
    public sealed class GridFooterAvg : GridFoooterNumericAggregateBase
    {
        #region Constructors.

        /// <summary>
        /// Initializes a new instance of <b>GridFooterAvg</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        public GridFooterAvg(string valueFieldName, Type valueDataType)
            : base(valueFieldName, valueDataType)
        {
        }

        /// <summary>
        /// Initializes a new instance of <b>GridFooterAvg</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        /// <param name="resultFormat">Result string format. Eg: "AVG: {0}". Nullable.</param>
        public GridFooterAvg(string valueFieldName, Type valueDataType, string resultFormat)
            : base(valueFieldName, valueDataType, resultFormat)
        {
        }

        /// <summary>
        /// Initializes a new instance of <b>GridFooterAvg</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        /// <param name="resultFormat">Result string format. Eg: "AVG: {0}". Nullable.</param>
        /// <param name="formatter">Formats numbers values. Nullable.</param>
        /// <param name="placementColumn">The name of the field/column in whose footer the computed value will be displayed. Nullable.</param>
        public GridFooterAvg(string valueFieldName, Type valueDataType, string resultFormat, IMessageFormatter formatter, string placementColumn)
            : base(valueFieldName, valueDataType, resultFormat, formatter, placementColumn)
        {
        }

        #endregion

        #region Compute aggregate.

        /// <summary>
        /// Computes and returns the integral sum of the provided values.
        /// </summary>
        /// <param name="numericValues">A collection of numeric values which are convertible to <see cref="System.Int64"/>.</param>
        /// <returns>Aggregate value.</returns>
        protected override long ComputeIntegralAggregate(IEnumerable numericValues)
        {
            long sum = 0;
            long count = 0;
            foreach (object value in numericValues)
            {
                sum += Convert.ToInt64(value);
                count++;
            }

            long avg = (count > 0) ? sum / count : 0;
            return avg;
        }

        /// <summary>
        /// Computes and returns the floating point sum of the provided values.
        /// </summary>
        /// <param name="numericValues">A collection of numeric values which are convertible to <see cref="System.Decimal"/>.</param>
        /// <returns>Aggregate value.</returns>
        protected override decimal ComputeFloatingPointAggregate(IEnumerable numericValues)
        {
            decimal sum = 0;
            long count = 0;
            foreach (object value in numericValues)
            {
                sum += Convert.ToDecimal(value);
                count++;
            }

            decimal avg = (count > 0) ? sum / count : 0;
            return avg;
        }

        #endregion
    }
}